package exec;

import context.Context;
import utils.FileUtils;
import utils.FormatUtils;
import utils.StringUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by baolong on 2016/2/22.
 */
public class GeneratorAPI {

    public static final String charset="utf-8";
    public static String apiProject="inapi";

    public static void main(String[] args) throws Exception {
        exec("E:\\work\\GFS_NEW_IntenlliJ\\SN\\branches\\SN-parent_0.0.1_BR",
                "inapi",
                "Test",
                "金融业务",
                new ArrayList<String>(){{
                    this.add("serviceA");
                    this.add("serviceB");
                    this.add("serviceC");
                }}

        );
    }


    public static void exec(String basePath,String apiProjectName,String apiName,String apiDesc ,List<String> serviceList) throws Exception{
        if(!apiProjectName.equals("inapi")&&!apiProjectName.equals("outapi")){
            throw new RuntimeException("在创建api时，apiProjectname必须为inapi或者outapi");
        }
        Context c = new Context();

        c.put("apiPath", basePath+"\\SN-"+apiProject+"\\src\\main\\java\\cn\\com\\gome\\sn\\"+apiProject+"\\controller");
        c.put("servicePath", basePath+"\\SN-"+apiProject+"\\src\\main\\java\\cn\\com\\gome\\sn\\"+apiProject+"\\service");
        c.put("serviceImplPath",basePath+"\\SN-"+apiProject+"\\src\\main\\java\\cn\\com\\gome\\sn\\"+apiProject+"\\service\\Impl");

        c.put("apiPackage","cn.com.gome.sn."+apiProject+".controller");
        c.put("servicePackage", "cn.com.gome.sn."+apiProject+".service");
        c.put("serviceImplPackage", "cn.com.gome.sn."+apiProject+".service.impl");


        //需要修改内容-------开始
        c.put("apiName", apiName);//接口名称
        c.put("apiDesc", apiDesc);//接口描述
        for(String service : serviceList){
            c.addtoList("serviceList", service);

        }

        if(serviceList!=null){
            for(String serviceName : serviceList){
                c.put("currentServiceName",serviceName);
                createService(c);
                createServiceImpl(c);
            }
        }

        createAPI(c);
    }

    public static void createAPI(Context c)  throws Exception {
        //创建文件夹
        String apiName = (String)c.get("apiName");
        String apiDesc = (String)c.get("apiDesc");
        String apiPath = (String)c.get("apiPath");
        String apiPackage = (String)c.get("apiPackage");
        String servicePath = (String)c.get("servicePath");
        String servicePackage = (String)c.get("servicePackage");
        String serviceImplPath = (String)c.get("serviceImplPath");
        String serviceImplPackage = (String)c.get("serviceImplPackage");
        if(!FileUtils.mkdirs(apiPath)){
            throw new Exception("文件夹["+apiPath+"]创建不成功");
        }
        String className = FormatUtils.firstBig(apiName)+"Api";
        String fileName = className+".java";
        File entityFile = new File(apiPath + File.separator+fileName);
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(entityFile),charset));

        //准备内容
        StringBuilder sb = new StringBuilder();
        sb.append("/**\r\n * Gome SN Generator \r\n */\r\n");
        sb.append("package " + apiPackage +";").append("\r\n").append("\r\n");
        sb.append("import java.util.Map;").append("\r\n");
        sb.append("import javax.servlet.http.HttpServletRequest;").append("\r\n");
        sb.append("import javax.servlet.http.HttpServletResponse;").append("\r\n");
        sb.append("import cn.com.gome.sn."+apiProject+".base.AdvanceApiBaseController;").append("\r\n");
        List<String> serviceList = (List<String>)c.get("serviceList");
        if(serviceList!=null){
            for(String serviceName : serviceList){
                sb.append("import cn.com.gome.sn."+apiProject+".service."+FormatUtils.firstBig(serviceName)+"Service;").append("\r\n");
            }
        }
        sb.append("import net.sf.json.JSONObject;").append("\r\n");
        sb.append("import org.springframework.beans.factory.annotation.Autowired;").append("\r\n");
        sb.append("import org.springframework.beans.factory.annotation.Value;").append("\r\n");
        sb.append("import org.springframework.stereotype.Controller;").append("\r\n");
        sb.append("import org.springframework.web.bind.annotation.RequestBody;").append("\r\n");
        sb.append("import org.springframework.web.bind.annotation.RequestMapping;").append("\r\n");
        sb.append("import org.springframework.web.bind.annotation.RequestMethod;").append("\r\n");
        sb.append("import cn.com.gome.frame.logger.HLogger;").append("\r\n");
        sb.append("import cn.com.gome.frame.logger.LoggerManager;").append("\r\n");
        sb.append("import cn.com.gome.sn."+apiProject+".utils.APPAESUtils;").append("\r\n");
        sb.append("import cn.com.gome.sn."+apiProject+".utils.JsonTools;").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("/**").append("\r\n");
        sb.append(" * "+apiDesc).append("\r\n");
        sb.append(" */").append("\r\n");
        sb.append("@Controller").append("\r\n");
        sb.append("@RequestMapping(\"/"+apiName.toLowerCase()+"\")").append("\r\n");
        sb.append("public class "+className+" extends AdvanceApiBaseController {").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("    protected HLogger logger = LoggerManager.getLoger(\"TestApi\");").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("    public final String charset = \"UTF-8\";").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("    @Value(\"#{"+apiProject+"['md5Key']}\")").append("\r\n");
        sb.append("    private String md5Key;").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("    @Value(\"#{"+apiProject+"['aesKey']}\")").append("\r\n");
        sb.append("    private String aesKey;").append("\r\n");
        sb.append("").append("\r\n");
        if(serviceList!=null){
            for(String serviceName : serviceList){
                sb.append("    @Autowired").append("\r\n");
                sb.append("    private "+FormatUtils.firstBig(serviceName)+"Service "+FormatUtils.firstSmall(serviceName)+"Service;").append("\r\n").append("\r\n");
            }
        }


        sb.append("    /**").append("\r\n");
        sb.append("     * 具有加密验签功能的api接口").append("\r\n");
        sb.append("     * @param request").append("\r\n");
        sb.append("     * @param response").append("\r\n");
        sb.append("     * @param requestjson").append("\r\n");
        sb.append("     * @return").append("\r\n");
        sb.append("     */").append("\r\n");
        sb.append("    @RequestMapping(value = \""+apiName.toLowerCase()+".do\", method = RequestMethod.POST, produces = {\"application/json;charset=UTF-8\"})").append("\r\n");
        sb.append("    public String "+apiName.toLowerCase()+"(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestjson) {").append("\r\n");
        sb.append("        logger.info(\""+className+"."+apiName.toLowerCase()+"--start\");").append("\r\n");
        sb.append("        logger.info(\"requestjson:\" + requestjson);").append("\r\n");
        sb.append("        // 返回值").append("\r\n");
        sb.append("        String responsejson = \"\";").append("\r\n");
        sb.append("        String reqMessageId = \"\";").append("\r\n");
        sb.append("        try {").append("\r\n");
        sb.append("            Map<String, Object> paramMap = JSONObject.fromObject(requestjson);").append("\r\n");
        sb.append("            reqMessageId = (String)paramMap.get(\"reqMessageId\");//请求ID").append("\r\n");
        sb.append("            String reqTime      = (String)paramMap.get(\"reqTime\");//请求时间").append("\r\n");
        sb.append("            String version      = (String)paramMap.get(\"version\");//版本号").append("\r\n");
        sb.append("            String systemNo     = (String)paramMap.get(\"systemNo\");//系统编号").append("\r\n");
        sb.append("            String encReqInfo   = (String)paramMap.get(\"encReqInfo\");//加密请求信息").append("\r\n");
        sb.append("            String reqType      = (String)paramMap.get(\"reqType\");//交易类型").append("\r\n");
        sb.append("            String sign         = (String)paramMap.get(\"sign\");//签名信息").append("\r\n");
        sb.append("            //请求参数校验").append("\r\n");
        sb.append("            if(!checkParamMap(paramMap)){").append("\r\n");
        sb.append("                responsejson=returnMsg(RESULT_FAIL,\"请求参数不全\",null,reqMessageId);").append("\r\n");
        sb.append("                logger.info(\"responsejson:\" + responsejson);").append("\r\n");
        sb.append("                return responsejson;").append("\r\n");
        sb.append("            }").append("\r\n");
        sb.append("            //MD5验签").append("\r\n");
        sb.append("            if(!validateMd5(systemNo, reqTime, encReqInfo, sign, md5Key)){").append("\r\n");
        sb.append("                responsejson=returnMsg(RESULT_FAIL,\"验签失败\",null,reqMessageId);").append("\r\n");
        sb.append("                logger.info(\"responsejson:\" + responsejson);").append("\r\n");
        sb.append("                return responsejson;").append("\r\n");
        sb.append("            }").append("\r\n");
        sb.append("            String reqJosn = APPAESUtils.decrypt(encReqInfo, aesKey);").append("\r\n");
        sb.append("            logger.info(\"接收"+apiProject+"接口请求数据\" + \",reqTime:\" + reqTime + \" reqJosn:\" + reqJosn);").append("\r\n");
        sb.append("            Map<String, Object> reqMap = JsonTools.parseJSON2Map(reqJosn);").append("\r\n");
        sb.append("            reqMap.put(\"reqMessageId\", reqMessageId);").append("\r\n");
        sb.append("            //业务逻辑处理").append("\r\n");
        sb.append("            Map<String, Object> retMap = null;").append("\r\n");
        sb.append("            if(\"10000000\".equals(reqType)) {").append("\r\n");
        sb.append("                responsejson=returnMsg(RESULT_SUCCESS,\"接口联通测试成功\",null,reqMessageId);").append("\r\n");
        sb.append("                logger.info(\"responsejson:\" + responsejson);").append("\r\n");
        sb.append("                return responsejson;").append("\r\n");
        if(serviceList!=null){
            for(int i=0;i<serviceList.size();i++){
                String reqType = "1"+ StringUtils.fillString((i+1) + "", '0', 7, false);
                sb.append("            } else if(\""+reqType+"\".equals(reqType)) {").append("\r\n");
                String serviceName = serviceList.get(i);
                sb.append("                retMap = " + serviceName + "Service.exec(reqMap);").append("\r\n");
            }
        }
        sb.append("            } else {").append("\r\n");
        sb.append("                responsejson=returnMsg(RESULT_FAIL,\"没有找到对应的reqType\",null,reqMessageId);").append("\r\n");
        sb.append("                logger.info(\"responsejson:\" + responsejson);").append("\r\n");
        sb.append("                return responsejson;").append("\r\n");
        sb.append("            }").append("\r\n");


        sb.append("            //RESCODE和RESDESC由SERVICE内确定").append("\r\n");
        sb.append("            responsejson = returnMsg(retMap, reqMessageId);").append("\r\n");
        sb.append("        } catch (Exception e) {").append("\r\n");
        sb.append("            logger.error(\"接口处理异常\", e);").append("\r\n");
        sb.append("            responsejson=returnMsg(RESULT_FAIL,\"接口处理异常\",null,reqMessageId);").append("\r\n");
        sb.append("            logger.info(\"responsejson:\" + responsejson);").append("\r\n");
        sb.append("            return responsejson;").append("\r\n");
        sb.append("        }").append("\r\n");
        sb.append("        logger.info(\""+className+"."+apiName.toLowerCase()+"--end\");").append("\r\n");
        sb.append("        return responsejson;").append("\r\n");
        sb.append("    }").append("\r\n");



        sb.append("    /**").append("\r\n");
        sb.append("     * 不具有加密验签功能的api接口").append("\r\n");
        sb.append("     * @param request").append("\r\n");
        sb.append("     * @param response").append("\r\n");
        sb.append("     * @param requestjson").append("\r\n");
        sb.append("     * @return").append("\r\n");
        sb.append("     */").append("\r\n");
        sb.append("    @RequestMapping(value = \""+apiName.toLowerCase()+"ne.do\", produces = {\"application/json;charset=UTF-8\"})").append("\r\n");
        sb.append("    public String "+apiName.toLowerCase()+"ne(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestjson) {").append("\r\n");
        sb.append("        logger.info(\""+className+"ne."+apiName.toLowerCase()+"--start\");").append("\r\n");
        sb.append("        logger.info(\"requestjson:\" + requestjson);").append("\r\n");
        sb.append("        // 返回值").append("\r\n");
        sb.append("        String responsejson = \"\";").append("\r\n");
        sb.append("        String reqMessageId = \"\";").append("\r\n");
        sb.append("        try {").append("\r\n");
        sb.append("            Map<String, Object> paramMap = JSONObject.fromObject(requestjson);").append("\r\n");
        sb.append("            reqMessageId = (String)paramMap.get(\"reqMessageId\");//请求ID").append("\r\n");
        sb.append("            String reqTime      = (String)paramMap.get(\"reqTime\");//请求时间").append("\r\n");
        sb.append("            String version      = (String)paramMap.get(\"version\");//版本号").append("\r\n");
        sb.append("            String systemNo     = (String)paramMap.get(\"systemNo\");//系统编号").append("\r\n");
        sb.append("            String reqType      = (String)paramMap.get(\"reqType\");//交易类型").append("\r\n");
        sb.append("            //请求参数校验").append("\r\n");
        sb.append("            if(!checkParamMapne(paramMap)){").append("\r\n");
        sb.append("                responsejson=returnMsg(RESULT_FAIL,\"请求参数不全\",null,reqMessageId);").append("\r\n");
        sb.append("                logger.info(\"responsejson:\" + responsejson);").append("\r\n");
        sb.append("                return responsejson;").append("\r\n");
        sb.append("            }").append("\r\n");
        sb.append("            logger.info(\"接收"+apiProject+"接口请求数据\" + \": paramMap:\" + paramMap);").append("\r\n");
        sb.append("            Map<String, Object> reqMap = paramMap;").append("\r\n");
        sb.append("            //业务逻辑处理").append("\r\n");
        sb.append("            Map<String, Object> retMap = null;").append("\r\n");
        sb.append("            if(\"10000000\".equals(reqType)) {").append("\r\n");
        sb.append("                responsejson=returnMsg(RESULT_SUCCESS,\"接口联通测试成功\",null,reqMessageId);").append("\r\n");
        sb.append("                logger.info(\"responsejson:\" + responsejson);").append("\r\n");
        sb.append("                return responsejson;").append("\r\n");
        if(serviceList!=null){
            for(int i=0;i<serviceList.size();i++){
                String reqType = "1"+ StringUtils.fillString((i+1) + "", '0', 7, false);
                sb.append("            } else if(\""+reqType+"\".equals(reqType)) {").append("\r\n");
                String serviceName = serviceList.get(i);
                sb.append("                retMap = " + serviceName + "Service.exec(reqMap);").append("\r\n");
            }
        }
        sb.append("            } else {").append("\r\n");
        sb.append("                responsejson=returnMsg(RESULT_FAIL,\"没有找到对应的reqType\",null,reqMessageId);").append("\r\n");
        sb.append("                logger.info(\"responsejson:\" + responsejson);").append("\r\n");
        sb.append("                return responsejson;").append("\r\n");
        sb.append("            }").append("\r\n");


        sb.append("            //RESCODE和RESDESC由SERVICE内确定").append("\r\n");
        sb.append("            responsejson = returnMsg(retMap, reqMessageId);").append("\r\n");
        sb.append("        } catch (Exception e) {").append("\r\n");
        sb.append("            logger.error(\"接口处理异常\", e);").append("\r\n");
        sb.append("            responsejson=returnMsg(RESULT_FAIL,\"接口处理异常\",null,reqMessageId);").append("\r\n");
        sb.append("            logger.info(\"responsejson:\" + responsejson);").append("\r\n");
        sb.append("            return responsejson;").append("\r\n");
        sb.append("        }").append("\r\n");
        sb.append("        logger.info(\""+className+"."+apiName.toLowerCase()+"--end\");").append("\r\n");
        sb.append("        return responsejson;").append("\r\n");
        sb.append("    }").append("\r\n");




        sb.append("}").append("\r\n");

        //增加标签
        pw.println(sb.toString());
        pw.close();
    }

    public static void createService(Context c)  throws Exception {
        //创建文件夹
        String apiName = (String)c.get("apiName");
        String apiDesc = (String)c.get("apiDesc");
        String apiPath = (String)c.get("apiPath");
        String apiPackage = (String)c.get("apiPackage");
        String servicePath = (String)c.get("servicePath");
        String servicePackage = (String)c.get("servicePackage");
        String serviceImplPath = (String)c.get("serviceImplPath");
        String serviceImplPackage = (String)c.get("serviceImplPackage");
        String currentServiceName = (String)c.get("currentServiceName");
        if(!FileUtils.mkdirs(servicePath)){
            throw new Exception("文件夹["+servicePath+"]创建不成功");
        }
        String className = FormatUtils.firstBig(currentServiceName)+"Service";
        String fileName = className+".java";
        File entityFile = new File(servicePath + File.separator+fileName);
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(entityFile),charset));

        //准备内容
        StringBuilder sb = new StringBuilder();
        sb.append("/**\r\n * Gome SN Generator \r\n */\r\n");
        sb.append("package " + servicePackage +";").append("\r\n").append("\r\n");
        sb.append("import java.util.Map;").append("\r\n");
        sb.append("public interface "+className+" {").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("    public Map<String, Object> exec(Map<String, Object> reqMap);").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("}").append("\r\n");
        //增加标签
        pw.println(sb.toString());
        pw.close();
    }

    public static void createServiceImpl(Context c)  throws Exception {
        //创建文件夹
        String apiName = (String)c.get("apiName");
        String apiDesc = (String)c.get("apiDesc");
        String apiPath = (String)c.get("apiPath");
        String apiPackage = (String)c.get("apiPackage");
        String servicePath = (String)c.get("servicePath");
        String servicePackage = (String)c.get("servicePackage");
        String serviceImplPath = (String)c.get("serviceImplPath");
        String serviceImplPackage = (String)c.get("serviceImplPackage");
        String currentServiceName = (String)c.get("currentServiceName");
        if(!FileUtils.mkdirs(serviceImplPath)){
            throw new Exception("文件夹["+serviceImplPath+"]创建不成功");
        }
        String className = FormatUtils.firstBig(currentServiceName)+"ServiceImpl";
        String fileName = className+".java";
        File entityFile = new File(serviceImplPath + File.separator+fileName);
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(entityFile),charset));

        //准备内容
        StringBuilder sb = new StringBuilder();
        sb.append("/**\r\n * Gome SN Generator \r\n */\r\n");
        sb.append("package " + serviceImplPackage +";").append("\r\n").append("\r\n");
        sb.append("import cn.com.gome.frame.logger.HLogger;").append("\r\n");
        sb.append("import cn.com.gome.frame.logger.LoggerManager;").append("\r\n");
        sb.append("import cn.com.gome.sn."+apiProject+".service." + FormatUtils.firstBig(currentServiceName) + "Service;").append("\r\n");
        sb.append("import org.springframework.stereotype.Service;").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("import java.util.HashMap;").append("\r\n");
        sb.append("import java.util.Map;").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("@Service").append("\r\n");
        sb.append("public class "+className+" implements "+FormatUtils.firstBig(currentServiceName)+"Service {").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("    protected HLogger logger = LoggerManager.getLoger(\"TestServiceImpl\");").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("    public Map<String, Object> exec(Map<String, Object> reqMap) {").append("\r\n");
        sb.append("        logger.info(\""+className+".exec--start\");").append("\r\n");
        sb.append("        //TODO 做业务处理").append("\r\n");
        sb.append("        Map<String, Object> resMap = new HashMap<String, Object>();").append("\r\n");
        sb.append("        resMap.put(\"resCode\", \"0002\");").append("\r\n");
        sb.append("        resMap.put(\"resDesc\", \"执行成功\");").append("\r\n");
        sb.append("        logger.info(\""+className+".exec--end\");").append("\r\n");
        sb.append("        return resMap;").append("\r\n");
        sb.append("    }").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("").append("\r\n");
        sb.append("}").append("\r\n");
        //增加标签
        pw.println(sb.toString());
        pw.close();
    }
}
